package snake.original;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Random;

import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.KeyStroke;

public class BackGround extends JFrame implements Runnable,ActionListener {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public JButton[][] snakeMatrix;

    // 战场标记
    public boolean[][] unable;

    public int row; // 背景行数

    public int column; // 背景列数

    public int length; // 单元像素宽度

    public int appRow; // 苹果行坐标

    public int appColumn; // 苹果列坐标

    public JPanel ground; // 背景面板

    public Point headPoint; // 头部坐标对象

    public String action; // 当前动作标识

    public ArrayList<JButton> list; // 蛇身队列

    public HashMap<JButton, Point> map; // 节点和坐标的映射

    /**
     * 构造方法
     * 
     * @param x
     *            行数
     * @param y
     *            列数
     * @param length
     *            单元像素
     */
    public BackGround(int x, int y, int length) {
        initGameComponents(x, y, length);
        initSnake();
        createApple();
        setupKeyboard();
        Thread testThread = new Thread(this);
        testThread.start();
    }

    /**
     * 初始化界面
     * 
     * @param x
     *            行数
     * @param y
     *            列数
     * @param length
     *            单元像素
     */
    private void initGameComponents(int x, int y, int length) {
//        JMenuBar menuBar = new JMenuBar();
//        menuBar.add(new JMenu("开始"));
//        this.setJMenuBar(menuBar);
        
        this.row = x;
        this.column = y;
        this.length = length;
        map = new HashMap<JButton, Point>();
        unable = new boolean[x][y];
        snakeMatrix = new JButton[x][y];

        ground = new JPanel();
        ground.setLayout(new GridLayout(x, y));
        ground.setSize(y * length, x * length);

        for (int i = 0; i < x; i++) {
            for (int j = 0; j < y; j++) {
                snakeMatrix[i][j] = new JButton();
                snakeMatrix[i][j].setBackground(Color.WHITE);
                unable[i][j] = false;
                map.put(snakeMatrix[i][j], new Point(i, j));
                ground.add(snakeMatrix[i][j]);
            }
        }

        this.getContentPane().add(ground);
        this.setSize(ground.getSize());
        this.setResizable(false);
    }

    /**
     * 初始化蛇
     */
    private void initSnake() {
        list = new ArrayList<JButton>();

        for (int i = row - 1; i >= 9; i--) {
            // 设置节点颜色
            snakeMatrix[i][9].setBackground(Color.BLACK);
            // 保存新增节点
            list.add(snakeMatrix[i][9]);
            // 标记结点位置被占用
            unable[i][9] = true;
        }
        headPoint = new Point(9, 9);
        action = "up";
    }

    /**
     * 生产苹果
     */
    private void createApple() {
        appRow = new Random().nextInt(row);
        appColumn = new Random().nextInt(column);
        // 如果位置被占用
        while (unable[appRow][appColumn]) {
            appRow = new Random().nextInt(row);
            appColumn = new Random().nextInt(column);
        }
        snakeMatrix[appRow][appColumn].setBackground(Color.RED);
    }

    /**
     * 捆绑键盘事件
     */
    private void setupKeyboard() {
        InputMap input = this.ground
                .getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        input.put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "left");
        input.put(KeyStroke.getKeyStroke(KeyEvent.VK_D, 0), "right");
        input.put(KeyStroke.getKeyStroke(KeyEvent.VK_W, 0), "up");
        input.put(KeyStroke.getKeyStroke(KeyEvent.VK_S, 0), "down");
        ActionMap actionMap = this.ground.getActionMap();
        actionMap.put("left", new AbstractAction()
        // 动作限制可以放到线程里面去
                {
                    /**
                     * 
                     */
                    private static final long serialVersionUID = 1L;

                    public void actionPerformed(ActionEvent e) {
                        action = action.equals("up") || action.equals("down") ? "left"
                                : action;
                    }
                });
        actionMap.put("right", new AbstractAction() {
            /**
             * 
             */
            private static final long serialVersionUID = -5280182173040571406L;

            public void actionPerformed(ActionEvent e) {
                action = action.equals("up") || action.equals("down") ? "right"
                        : action;
            }
        });
        actionMap.put("up", new AbstractAction() {
            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                action = action.equals("left") || action.equals("right") ? "up"
                        : action;
            }
        });
        actionMap.put("down", new AbstractAction() {
            /**
             * 
             */
            private static final long serialVersionUID = 1L;

            public void actionPerformed(ActionEvent e) {
                action = action.equals("left") || action.equals("right") ? "down"
                        : action;
            }
        });
    }

    /**
     * 程序入口方法
     * 
     * @param args
     */
    public static void main(String[] args) {
        JFrame test = new BackGround(15, 15, 15);
        test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
        test.setLocation((d.width - test.getSize().width) / 2, (d.height - test
                .getSize().height) / 2);
        test.setVisible(true);
    }

    /**
     * 主线程
     */
    public void run() {
        boolean runable = false;
        boolean eat = false;
        JButton lastButton = null;
        List<Point> eatList = new ArrayList<Point>();
        Point point = null;

        while (runable) {
            // 获得头部坐标
            int x = headPoint.x;
            int y = headPoint.y;
            // 根据键盘动作设置头部新坐标
            if (action.equals("up")) {
                x -= 1;
            } else if (action.equals("left")) {
                y -= 1;
            } else if (action.equals("right")) {
                y += 1;
            } else if (action.equals("down")) {
                x += 1;
            }
            // 如果碰到墙或自己
            if (x == row || x == -1 || y == column || y == -1
                    || unable[x][y] == true) {
                runable = false;
                break;
            }

            // 新头部的坐标
            headPoint.move(x, y);
            // 设置新头部的颜色
            snakeMatrix[x][y].setBackground(Color.BLACK);
            // 增加头部节点
            list.add(snakeMatrix[x][y]);
            // 设置被占用
            unable[x][y] = true;

            // 找出尾巴节点
            lastButton = list.get(0);
            // 找出旧尾巴的坐标
            point = map.get(lastButton);
            // 清除颜色
            lastButton.setBackground(Color.WHITE);
            // 去掉节点
            list.remove(0);
            // 标记坐标位置未被占用
            unable[point.x][point.y] = false;
            
            // 吃到苹果
            if (x == appRow && y == appColumn) {
                createApple();
                eatList.add(new Point(x, y));
                eat = true;
            }
            // 尾巴到达苹果点的位置(改吃法增长滞后)
            if (eat == true && point.equals(eatList.get(0))) {
                list.add(0, snakeMatrix[point.x][point.y]);
                unable[point.x][point.y] = true;
                snakeMatrix[point.x][point.y].setBackground(Color.BLACK);
                eatList.remove(0);
                eat = eatList.size() == 0 ? false : true;
            }

            try {
                // 休眠时间（此时间决定蛇移动的速度）
                Thread.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("线程异常中断");
                e.printStackTrace();
            }
        }
    }

    public void actionPerformed(ActionEvent e) {
        if ("disable".equals(e.getActionCommand())) {

        }
    }
}
